﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using ZuesControls.Enums;
using ZuesControls.Helpers;
using ZuesControls.Models;
using ZuesControls.Mvvm;







namespace ZuesControls.Controls
{
    public class ZSNavigate : ContentControl
    {
        public ICommand NavItemInernalClickCommand { get; }
        private Border PART_NavHost;
        private ListBox? itemsControl;
        public ToggleButton? PART_ToggleButton { get; private set; }
        private RepeatButton? _scrollUpButton;
        private RepeatButton? _scrollDownButton;
        private double CurrenNavWidth = 0;
        private TextBlock _header;
        public Window ParentWin { get; set; }

        static ZSNavigate()
        {

            DefaultStyleKeyProperty.OverrideMetadata(typeof(ZSNavigate), new FrameworkPropertyMetadata(typeof(ZSNavigate)));
        }

        public ZSNavigate()
        {
            this.Unloaded += ZSNavigate_Unloaded;
            this.DataContextChanged += ZSNavigate_DataContextChanged;
            this.NavItemInernalClickCommand = new RelayCommand<Tuple<object, MouseButtonEventArgs>>(OnNavItemClick);
        }

        private void OnNavItemClick(Tuple<object, object>? model)
        {

            if (this.NavItemClickCommand != null)
            {
                this.NavItemClickCommand.Execute(model);
            }
        }

        private void Test(object p)
        {
            var sdf = 1;
        }

        public static readonly DependencyProperty ItemContainerStyleProperty = 
         DependencyProperty.Register(nameof(ItemContainerStyle), typeof(Style), typeof(ZSNavigate), new PropertyMetadata(null));

        public Style ItemContainerStyle
        {
            get => (Style)GetValue(ItemContainerStyleProperty);
            set => SetValue(ItemContainerStyleProperty, value);
        }



        public static readonly DependencyProperty NavItemClickCommandProperty =
      DependencyProperty.Register("NavItemClickCommand", typeof(RelayCommand<NavigateModel>), typeof(ZSNavigate), new PropertyMetadata(null));

        public RelayCommand<NavigateModel> NavItemClickCommand
        {
            get { return (RelayCommand<NavigateModel>)GetValue(NavItemClickCommandProperty); }
            set { SetValue(NavItemClickCommandProperty, value); }
        }

        public ScreenSize ScreenSize
        {
            get { return (ScreenSize)GetValue(ScreenSizeProperty); }
            set { SetValue(ScreenSizeProperty, value); }
        }

        public static readonly DependencyProperty ScreenSizeProperty =
            DependencyProperty.Register("ScreenSize", typeof(ScreenSize), typeof(ZSNavigate), new PropertyMetadata(ScreenSize.Unknown));


        public bool IsNavExpanded
        {
            get { return (bool)GetValue(IsNavExpandedProperty); }
            set { SetValue(IsNavExpandedProperty, value); }
        }

        public static readonly DependencyProperty IsNavExpandedProperty =
            DependencyProperty.Register("IsNavExpanded", typeof(bool), typeof(ZSNavigate), new PropertyMetadata(true, OnIsNavExpandedPropertyChanged));

        public ObservableCollection<NavigateModel> NavigateModelList
        {
            get { return (ObservableCollection<NavigateModel>)GetValue(NavigateModelListProperty); }
            set { SetValue(NavigateModelListProperty, value); }
        }

        public static readonly DependencyProperty NavigateModelListProperty =
            DependencyProperty.Register("NavigateModelList", typeof(ObservableCollection<NavigateModel>), typeof(ZSNavigate), new PropertyMetadata(null, OnNavigateModelListPropertyChanged));


        private ListBox PART_NavList;
        private ScrollViewer _scrollViewer;

        private void ApplyTextAnimations()
        {
            this.PART_NavList = this.GetTemplateChild("PART_NavList") as ListBox;

        }

        public NavigateModel NavigateModelSelect
        {
            get { return (NavigateModel)GetValue(NavigateModelSelectProperty); }
            set { SetValue(NavigateModelSelectProperty, value); }
        }

        public static readonly DependencyProperty NavigateModelSelectProperty =
            DependencyProperty.Register("NavigateModelSelect", typeof(NavigateModel), typeof(ZSNavigate), new PropertyMetadata(null));

        public NavType NavType
        {
            get { return (NavType)GetValue(NavTypeProperty); }
            set { SetValue(NavTypeProperty, value); }
        }

        public static readonly DependencyProperty NavTypeProperty =
            DependencyProperty.Register("NavType", typeof(NavType), typeof(ZSNavigate), new PropertyMetadata(NavType.Unknown, OnNavTypePropertyChanged));

        public NavStatus NavStatus
        {
            get { return (NavStatus)GetValue(NavStatusProperty); }
            set { SetValue(NavStatusProperty, value); }
        }

        public static readonly DependencyProperty NavStatusProperty =
            DependencyProperty.Register("NavStatus", typeof(NavStatus), typeof(ZSNavigate), new PropertyMetadata(NavStatus.Unknown, OnNavStatusPropertyChanged));

        private static void OnNavStatusPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var rsNavigate = (ZSNavigate)d;
            rsNavigate.UpateNavVisualState();
        }

        private static void OnNavTypePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }

        private static void OnIsNavExpandedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var rsNavigate = (ZSNavigate)d;
            rsNavigate.UpateNavVisualState();
          
        }

      

        private void ApplyTextAnimation(TextBlock textBlock, bool isExpanded)
        {
            if (!(textBlock.RenderTransform is TransformGroup group))
            {
                group = new TransformGroup();
                group.Children.Add(new ScaleTransform(1, 1));
                group.Children.Add(new TranslateTransform(0, 0));
                textBlock.RenderTransform = group;
                textBlock.RenderTransformOrigin = new Point(0.3, 0.3);
            }

            var scale = group.Children.OfType<ScaleTransform>().FirstOrDefault();
            var move = group.Children.OfType<TranslateTransform>().FirstOrDefault();

            if (scale == null || move == null) return;

            // 设置动画目标
            double scaleTo = isExpanded ? 0 : 1.0;
            double moveXTo = isExpanded ? -35 : 0;
            double moveYTo = isExpanded ? 10 : 0;

            var duration = TimeSpan.FromMilliseconds(300);

            scale.BeginAnimation(ScaleTransform.ScaleXProperty, new DoubleAnimation(scaleTo, duration));
            scale.BeginAnimation(ScaleTransform.ScaleYProperty, new DoubleAnimation(scaleTo, duration));
            move.BeginAnimation(TranslateTransform.XProperty, new DoubleAnimation(moveXTo, duration));
            move.BeginAnimation(TranslateTransform.YProperty, new DoubleAnimation(moveYTo, duration));
        }

        private void UpateNavVisualState()
        {
            //手动优先级最高
            if (this.IsNavExpanded)
            {
                this.NavStatus = NavStatus.Expanded;
            }
            else
            {
                this.NavStatus = NavStatus.Collapsed;
            }
            if (this.NavStatus == NavStatus.Expanded)
            {
                AnimateNavHostWidth(this.MaxWidth, TimeSpan.FromSeconds(0.2));
            }
            else
            {
                AnimateNavHostWidth(this.MinWidth, TimeSpan.FromSeconds(0.2));
            }

        }
        private void AnimateNavHostWidth(double toWidth, TimeSpan duration)
        {
            if (this.CurrenNavWidth == MaxWidth)
            {
                var animation = new DoubleAnimation
                {
                    From = MaxWidth,
                    To = MinWidth,
                    Duration = duration
                };
                this.PART_NavHost?.BeginAnimation(FrameworkElement.WidthProperty, animation);
            }
            else
            {
                var animation = new DoubleAnimation
                {
                    From = MinWidth,
                    To = MaxWidth,
                    Duration = duration
                };
                this.PART_NavHost?.BeginAnimation(FrameworkElement.WidthProperty, animation);
            }
            this.CurrenNavWidth = toWidth;
        }
        private void OnNavItemClick(Tuple<object, MouseButtonEventArgs> parameter)
        {
            var model = parameter.Item1 as NavigateModel;
            this.UpdateNavigateModelSelect(model);
            if (this.NavItemClickCommand != null)
            {
                this.NavItemClickCommand.Execute(model);
            }
        }

        private void UpdateNavigateModelSelect(NavigateModel? model)
        {
            //获取到选择项
            if (model != null)
            {
                foreach (var item in this.NavigateModelList)
                {
                    item.IsSelect = false;
                }
                model.IsSelect = true;
            }

            this.NavigateModelSelect = model;
        }

        private static void OnNavigateModelListPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control = d as ZSNavigate;
            if (control == null) return;

            // 延迟执行，等模板和容器都加载完
            control.Dispatcher.BeginInvoke(new Action(() =>
            {
                control.ApplyTextAnimations();
            }), System.Windows.Threading.DispatcherPriority.Loaded);
        }
        private void ZSNavigate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {

        }

        private void ZSNavigate_Unloaded(object sender, RoutedEventArgs e)
        {

        }
        public override void OnApplyTemplate()
        {
            this.PART_NavHost = this.GetTemplateChild(nameof(this.PART_NavHost)) as Border;
            this.itemsControl = GetTemplateChild("PART_NavList") as ListBox;
            PART_ToggleButton = this.GetTemplateChild("PART_ToggleButton") as ToggleButton;
            _scrollUpButton = GetTemplateChild("PART_ScrollUpButton") as RepeatButton;
            _scrollDownButton = GetTemplateChild("PART_ScrollDownButton") as RepeatButton;
            this.ParentWin = this.TryFindParent<Window>();
            this.Loaded += (s, e) =>
            {
                _scrollViewer = VisualHelper.FindChild<ScrollViewer>(this);

                if (_scrollUpButton != null)
                    _scrollUpButton.Click += (s1, e1) => _scrollViewer?.ScrollToVerticalOffset(_scrollViewer.VerticalOffset - 30);

                if (_scrollDownButton != null)
                    _scrollDownButton.Click += (s2, e2) => _scrollViewer?.ScrollToVerticalOffset(_scrollViewer.VerticalOffset + 30);
            };
            if (this.ParentWin != null)
            {
                this.ParentWin.SizeChanged -= ParentWin_SizeChanged;
                this.ParentWin.SizeChanged += ParentWin_SizeChanged;
            }
            PART_NavHost.Width = MinWidth;


        }

        private void ParentWin_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            this.UpdateNavType();
        }

        private void UpdateNavType()
        {
            if (this.ParentWin == null)
            {
                return;
            }
            var width = this.ParentWin.Width;
            if (width <= 950 && PART_ToggleButton.IsChecked == false)
            {
                ScreenSize = ScreenSize.Small;
                this.IsNavExpanded = true;
               // AnimateNavHostWidth(this.MinWidth, TimeSpan.FromSeconds(0.2));
            }
            else if (width >= 950 && PART_ToggleButton.IsChecked == true)
            {
                this.IsNavExpanded = false;
            }

        }

      
    }
}
